home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / nroff / command.c next >
C/C++ Source or Header  |  1990-07-23  |  17KB  |  1,004 lines

  1. /*
  2.  *    command.c - command input parser/processor for nroff text processor
  3.  *
  4.  *    adapted for atariST/TOS by Bill Rosenkranz 11/89
  5.  *    net:    rosenkra@hall.cray.com
  6.  *    CIS:    71460,17
  7.  *    GENIE:    W.ROSENKRANZ
  8.  *
  9.  *    original author:
  10.  *
  11.  *    Stephen L. Browning
  12.  *    5723 North Parker Avenue
  13.  *    Indianapolis, Indiana 46220
  14.  *
  15.  *    history:
  16.  *
  17.  *    - Originally written in BDS C;
  18.  *    - Adapted for standard C by W. N. Paul
  19.  *    - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz
  20.  */
  21.  
  22. #undef NRO_MAIN                    /* extern globals */
  23.  
  24. #include <stdio.h>
  25. #include "nroff.h"
  26.  
  27.  
  28.  
  29. /*------------------------------*/       
  30. /*    comand            */
  31. /*------------------------------*/       
  32. comand (p)
  33. register char  *p;
  34. {
  35.  
  36. /*
  37.  *    main command processor
  38.  */
  39.  
  40.     register int    i;
  41.     register int    ct;
  42.     register int    val;
  43.     register int       indx;
  44.     int        newval;
  45.     int         spval;
  46.     char        argtyp;
  47.     char        name[MAXLINE];
  48.     char        macexp[MXMLEN];
  49.     int        tmp;
  50.     char           *pfs;
  51.     char        fs[20];
  52.  
  53.  
  54.     /*
  55.      *   get command code
  56.      */
  57.     ct = comtyp (p, macexp);
  58.  
  59.     /*
  60.      *   error?
  61.      */
  62.     if (ct == UNKNOWN)
  63.     {
  64.         fprintf (err_stream,
  65.             "***%s: unrecognized command %s\n", myname, p);
  66.         return;
  67.     }
  68.  
  69.     /*
  70.      *   ignore comments
  71.      */
  72.     if (ct == COMMENT)
  73.         return;
  74.  
  75.  
  76.     /*
  77.      *   do escape expansion on command line args
  78.      */
  79.     expesc (p, name);
  80.  
  81.  
  82.     /*
  83.      *   get value of command
  84.      */
  85.     val = getval (p, &argtyp);
  86.  
  87.  
  88.     /*
  89.      *   do the command
  90.      */
  91.     switch (ct)
  92.     {
  93.     /* set (¶m, val, type, defval, minval, maxval) */
  94.     case FC:
  95.         /*
  96.          *   field delim/pad chars
  97.          *
  98.          *   .fc [delim] [pad]
  99.          */
  100.         fprintf (err_stream, "***%s: .fc not available\n", myname);
  101.         break;
  102.     case TR:
  103.         /*
  104.          *   translate
  105.          *
  106.          *   .tr ab...
  107.          */
  108.         fprintf (err_stream, "***%s: .tr not available\n", myname);
  109.         break;
  110.  
  111.  
  112.  
  113.  
  114.     case AD:
  115.         /*
  116.          *   adjust
  117.          *
  118.          *   .ad [mode]
  119.          */
  120.         p = skipwd (p);
  121.         p = skipbl (p);
  122.  
  123.         switch (*p)
  124.         {
  125.         case 'l':
  126.             dc.adjval = ADJ_LEFT;
  127.             dc.juval  = YES;
  128.             break;
  129.         case 'r':
  130.             dc.adjval = ADJ_RIGHT;
  131.             dc.juval  = YES;
  132.             break;
  133.         case 'c':
  134.             dc.adjval = ADJ_CENTER;
  135.             dc.juval  = YES;
  136.             break;
  137.         case 'b':
  138.         case 'n':
  139.             dc.adjval = ADJ_BOTH;
  140.             dc.juval  = YES;
  141.             break;
  142.         default:
  143.             break;
  144.         }
  145.         break;
  146.     case AF:
  147.         /*
  148.          *   assign format to number reg
  149.          *
  150.          *   .af R {1,a,A,i,I,0...1}
  151.          */
  152.         p = skipwd (p);
  153.         p = skipbl (p);
  154.         if (!isalpha (*p))
  155.         {
  156.             fprintf (err_stream,
  157.                 "***%s: invalid or missing number register name\n",
  158.                 myname);
  159.         }
  160.         else
  161.         {
  162.             /*
  163.              *   number register format is 1,a,A,i,I,0...1
  164.              *   default is 1. for 0001 format, store num dig
  165.              *   or'ed with 0x80, up to 8 digits.
  166.              */
  167.             indx = tolower (*p) - 'a';
  168.             p = skipwd (p);
  169.             p = skipbl (p);
  170.             if (*p == '1')
  171.                 dc.nrfmt[indx] = '1';
  172.             else if (*p == 'a')
  173.                 dc.nrfmt[indx] = 'a';
  174.             else if (*p == 'A')
  175.                 dc.nrfmt[indx] = 'A';
  176.             else if (*p == 'i')
  177.                 dc.nrfmt[indx] = 'i';
  178.             else if (*p == 'I')
  179.                 dc.nrfmt[indx] = 'I';
  180.             else if (*p == '0')
  181.             {
  182.                 for (i = 0; isdigit (p[i]); i++)
  183.                     ;
  184.                 dc.nrfmt[indx] = (char) (i);
  185.                 if (dc.nrfmt[indx] <= 0)
  186.                     dc.nrfmt[indx] = '1';
  187.                 else if (dc.nrfmt[indx] > 8)
  188.                 {
  189.                     dc.nrfmt[indx]  = 8;
  190.                     dc.nrfmt[indx] |= 0x80;
  191.                 }
  192.                 else
  193.                     dc.nrfmt[indx] |= 0x80;
  194.  
  195.             }
  196.             else
  197.                 dc.nrfmt[indx] = '1';
  198.         }
  199.         break;
  200.     case BD:
  201.         /*
  202.          *   embolden font (IGNORED)
  203.          *
  204.          *   .bd [S] F N
  205.          */
  206.         break;
  207.     case BO:
  208.         /*
  209.          *   bold face
  210.          *
  211.          *   .bo [N]
  212.          */
  213.         set (&dc.boval, val, argtyp, 1, 0, HUGE);
  214.         dc.cuval = dc.ulval = 0;
  215.         break;
  216.     case BP:
  217.         /*
  218.          *   begin page
  219.          *
  220.          *   .bp [+/-N]
  221.          */
  222.         if (pg.lineno > 0)
  223.             space (HUGE);
  224.         set (&pg.curpag, val, argtyp, pg.curpag + 1, -HUGE, HUGE);
  225.         pg.newpag = pg.curpag;
  226.         set_ireg ("%", pg.newpag, 0);
  227.         break;
  228.     case BR:
  229.         /*
  230.          *   break (page)
  231.          *
  232.          *   .br
  233.          */
  234.         robrk ();
  235.         break;
  236.     case BS:
  237.         /*
  238.          *   backspc in output
  239.          *
  240.          *   .bs [N]
  241.          */
  242.         set (&dc.bsflg, val, argtyp, 1, 0, 1);
  243.         break;
  244.     case C2:
  245.         /*
  246.          *   nobreak char
  247.          *
  248.          *   .c2 [c=']
  249.          */
  250.         if (argtyp == '\r' || argtyp == '\n')
  251.             dc.nobrchr = '\'';
  252.         else
  253.             dc.nobrchr = argtyp;
  254.         break;
  255.     case CC:
  256.         /*
  257.          *   command character
  258.          *
  259.          *   .cc [c=.]
  260.          */
  261.         if (argtyp == '\r' || argtyp == '\n')
  262.             dc.cmdchr = '.';
  263.         else
  264.             dc.cmdchr = argtyp;
  265.         break;
  266.     case CE:
  267.         /*
  268.          *   center
  269.          *
  270.          *   .ce [N]
  271.          */
  272.         robrk ();
  273.         set (&dc.ceval, val, argtyp, 1, 0, HUGE);
  274.         break;
  275.     case CS:
  276.         /*
  277.          *   constant space char (IGNORED)
  278.          *
  279.          *   .cs F N M
  280.          */
  281.         break;
  282.     case CU:
  283.         /*
  284.          *   continuous underline
  285.          *
  286.          *   .cu [N]
  287.          */
  288.         set (&dc.cuval, val, argtyp, 1, 0, HUGE);
  289.         dc.ulval = dc.boval = 0;
  290.         break;
  291.     case DE:
  292.         /*
  293.          *   define macro
  294.          *
  295.          *   .de name [end]
  296.          */
  297.         ignoring = FALSE;
  298.         defmac (p, sofile[dc.flevel]);
  299.         break;
  300.     case DS:
  301.         /*
  302.          *   define string
  303.          *
  304.          *   .ds name string
  305.          */
  306.         defstr (p);
  307.         break;
  308.     case EC:
  309.         /*
  310.          *   escape char
  311.          *
  312.          *   .ec [c=\]
  313.          */
  314.         if (argtyp == '\r' || argtyp == '\n')
  315.             dc.escchr = '\\';
  316.         else
  317.             dc.escchr = argtyp;
  318.         dc.escon = YES;
  319.         break;
  320.     case EF:
  321.         /*
  322.          *   even footer
  323.          *
  324.          *   .ef "a" "b" "c"
  325.          */
  326.         gettl (p, pg.efoot, &pg.eflim[0]);
  327.         break;
  328.     case EH:
  329.         /*
  330.          *   even header
  331.          *
  332.          *   .eh "a" "b" "c"
  333.          */
  334.         gettl (p, pg.ehead, &pg.ehlim[0]);
  335.         break;
  336.     case EN:
  337.         /*
  338.          *   end macro def (should not get one here...)
  339.          *
  340.          *   .en or ..
  341.          */
  342.         fprintf (err_stream, "***%s: missing .de command\n", myname);
  343.         break;
  344.     case EO:
  345.         /*
  346.          *   escape off
  347.          *
  348.          *   .eo
  349.          */
  350.         dc.escon = NO;
  351.         break;
  352.     case FI:
  353.         /*
  354.          *   fill
  355.          *
  356.          *   .fi
  357.          */
  358.         robrk ();
  359.         dc.fill = YES;
  360.         break;
  361.     case FL:
  362.         /*
  363.          *   flush NOW
  364.          *
  365.          *   .fl
  366.          */
  367.         fflush (out_stream);
  368.         break;
  369.     case FO:
  370.         /*
  371.          *   footer
  372.          *
  373.          *   .fo "a" "b" "c"
  374.          */
  375.         gettl (p, pg.efoot, &pg.eflim[0]);
  376.         gettl (p, pg.ofoot, &pg.oflim[0]);
  377.         break;
  378.     case FT:
  379.         /*
  380.          *   font change
  381.          *
  382.          *   .ft {R,I,B,S,P}
  383.          *
  384.          *   the way it's implemented here, it causes a break
  385.          *   rather than be environmental...
  386.          */
  387.         p = skipwd (p);
  388.         p = skipbl (p);
  389.         if (!isalpha (*p))
  390.         {
  391.             fprintf (err_stream,
  392.                 "***%s: invalid or missing font name\n",
  393.                 myname);
  394.         }
  395.         else
  396.         {
  397.             pfs = &fs[0];
  398.  
  399.             fontchange (*p, pfs);
  400.  
  401.             robrk ();
  402.             fflush (out_stream);
  403.             fprintf (out_stream, "%s", pfs);
  404.             fflush (out_stream);
  405.         }
  406.         break;
  407.     case TL:
  408.     case HE:
  409.         /*
  410.          *   header (both are currently identical. .he is -me)
  411.          *
  412.          *   .tl "a" "b" "c"
  413.          *   .he "a" "b" "c"
  414.          */
  415.         gettl (p, pg.ehead, &pg.ehlim[0]);
  416.         gettl (p, pg.ohead, &pg.ohlim[0]);
  417.         break;
  418.     case IG:
  419.         /*
  420.          *   ignore input lines
  421.          *
  422.          *   .ig name
  423.          */
  424.         ignoring = TRUE;
  425.         defmac (p, sofile[dc.flevel]);
  426.         break;
  427.     case IN:
  428.         /*
  429.          *   indenting
  430.          *
  431.          *   .in [+/-N]
  432.          */
  433.         set (&dc.inval, val, argtyp, 0, 0, dc.rmval - 1);
  434.         set_ireg (".i", dc.inval, 0);
  435.         dc.tival = dc.inval;
  436.         break;
  437.     case JU:
  438.         /*
  439.          *   justify
  440.          *
  441.          *   .ju
  442.          */
  443.         dc.juval = YES;
  444.         break;
  445.     case LL:
  446.         /*
  447.          *   line length
  448.          *
  449.          *   .ll [+/-N]
  450.          *   .rm [+/-N]
  451.          */
  452.         set (&dc.rmval, val, argtyp, PAGEWIDTH, dc.tival + 1, HUGE);
  453.         set (&dc.llval, val, argtyp, PAGEWIDTH, dc.tival + 1, HUGE);
  454.         set_ireg (".l", dc.llval, 0);
  455.         break;
  456.     case LS:
  457.         /*
  458.          *   line spacing
  459.          *
  460.          *   .ls [+/-N=+1]
  461.          */
  462.         set (&dc.lsval, val, argtyp, 1, 1, HUGE);
  463.         set_ireg (".v", dc.lsval, 0);
  464.         break;
  465.     case LT:
  466.         /*
  467.          *   title length
  468.          *
  469.          *   .lt N
  470.          */
  471.         set (&dc.ltval, val, argtyp, PAGEWIDTH, 0, HUGE);
  472.         pg.ehlim[RIGHT] = dc.ltval;
  473.         pg.ohlim[RIGHT] = dc.ltval;
  474.         break;
  475.     case M1:
  476.         /*
  477.          *   topmost margin
  478.          *
  479.          *   .m1 N
  480.          */
  481.         set (&pg.m1val, val, argtyp, 2, 0, HUGE);
  482.         break;
  483.     case M2:
  484.         /*
  485.          *   second top margin
  486.          *
  487.          *   .m2 N
  488.          */
  489.         set (&pg.m2val, val, argtyp, 2, 0, HUGE);
  490.         break;
  491.     case M3:
  492.         /*
  493.          *   1st bottom margin
  494.          *
  495.          *   .m3 N
  496.          */
  497.         set (&pg.m3val, val, argtyp, 2, 0, HUGE);
  498.         pg.bottom = pg.plval - pg.m4val - pg.m3val;
  499.         break;
  500.     case M4:
  501.         /*
  502.          *   bottom-most marg
  503.          *
  504.          *   .m4 N
  505.          */
  506.         set (&pg.m4val, val, argtyp, 2, 0, HUGE);
  507.         pg.bottom = pg.plval - pg.m4val - pg.m3val;
  508.         break;
  509.     case MACRO:
  510.         /*
  511.          *   macro expansion
  512.          *
  513.          *   (internal)
  514.          */
  515.         maceval (p, macexp);
  516.         break;
  517.     case NA:
  518.         /*
  519.          *   no adjust
  520.          *
  521.          *   .na
  522.          */
  523.         dc.adjval = ADJ_OFF;
  524.         dc.juval  = NO;